package com.applcn.shop.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.applcn.core.base.PageVO;
import com.applcn.core.base.Result;
import com.applcn.shop.constant.*;
import com.applcn.shop.dto.CreateShopDTO;
import com.applcn.shop.dto.ShopInfoDTO;
import com.applcn.shop.dto.UserShopPageDTO;
import com.applcn.shop.repo.entity.ShopBindEntity;
import com.applcn.shop.repo.entity.ShopEntity;
import com.applcn.shop.repo.entity.ShopIdentificationEntity;
import com.applcn.shop.repo.repository.ShopBindRepository;
import com.applcn.shop.repo.repository.ShopIdentificationRepository;
import com.applcn.shop.repo.repository.ShopRepository;
import com.applcn.shop.threadlocal.ShopRequestContextHolder;
import com.applcn.user.client.UserClient;
import com.applcn.user.dto.InitShopMenuDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * com.applcn.order.service
 * Description:
 *
 * @author: 大妖怪
 * @date: 2020-02-22 17:09
 */
@Service
@RequiredArgsConstructor
public class ShopService {

    private final ShopRepository shopRepository;
    private final ShopBindRepository shopBindRepository;
    private final ShopIdentificationRepository shopIdentificationRepository;
    private final UserClient userClient;

    /**
     * 通过id列表查询店铺列表
     *
     * @param ids
     * @return
     */
    public Result listShopByIds(List<Long> ids) {
        List<ShopEntity> shopEntityList = shopRepository.listByIds(ids);
        List<ShopInfoDTO> shopInfoDTOList = new ArrayList<>();
        for (ShopEntity shopEntity : shopEntityList) {
            ShopInfoDTO shopInfoDTO = new ShopInfoDTO();
            shopInfoDTO.setId(shopEntity.getId());
            shopInfoDTO.setMerchantId(shopEntity.getMerchantId());
            shopInfoDTOList.add(shopInfoDTO);
        }

        return Result.ok().putData(shopInfoDTOList);
    }

    /**
     * 创建店铺
     *
     * @param dto
     * @return
     */
    @GlobalTransactional(timeoutMills = 300000, name = "create-shop")
    public Result createShop(CreateShopDTO dto) {
        AuthTypeEnum authType = AuthTypeEnum.getAuthType(dto.getAuthType());
        Assert.notNull(authType, "认证类型不正确！");
        if (authType == AuthTypeEnum.ENTERPRISE) {
            Assert.notBlank(dto.getLicense(), "企业营业执照不能为空！");
        }

        Long userId = ShopRequestContextHolder.getUserId();
        Assert.notNull(userId, "用户未登录");
        Long merchantId = ShopRequestContextHolder.getMerchantId();
        Assert.notNull(merchantId, "商户未登录");
        ShopVersionEnum version = ShopVersionEnum.getVersion(dto.getShopVersion());
        Assert.notNull(version, "版本不正确");

        // 创建店铺
        ShopEntity shopEntity = new ShopEntity();
        shopEntity.setUserId(userId);
        shopEntity.setMerchantId(merchantId);
        shopEntity.setUniqueShopName(dto.getUniqueShopName());
        shopEntity.setShopExplain(dto.getShopExplain());
        shopEntity.setShopLogo(dto.getShopLogo());
        shopEntity.setCategoryId(dto.getCategoryId());
        shopEntity.setShopStatus(ShopStatusEnum.UN_PASS);
        shopEntity.setShopVersion(version);
        // TODO 店铺权限暂定1年
        shopEntity.setExpireTime(DateUtil.offsetMonth(new Date(), 12));
        shopRepository.save(shopEntity);

        // 创建店铺认证信息
        ShopIdentificationEntity shopIdentificationEntity = new ShopIdentificationEntity();
        shopIdentificationEntity.setShopId(shopEntity.getId());
        shopIdentificationEntity.setAuthType(authType);
        shopIdentificationEntity.setRealName(dto.getRealName());
        shopIdentificationEntity.setLicense(dto.getLicense());
        shopIdentificationEntity.setFrontOfIdCard(dto.getFrontOfIdCard());
        shopIdentificationEntity.setReverseOfIdCard(dto.getReverseOfIdCard());
        shopIdentificationEntity.setVerifyStatus(VerifyStatusEnum.PENDING);
        shopIdentificationRepository.save(shopIdentificationEntity);

        // 创建店铺绑定关系
        ShopBindEntity shopBindEntity = new ShopBindEntity();
        shopBindEntity.setMerchantId(merchantId);
        shopBindEntity.setShopBindStatus(ShopBindStatusEnum.ON);
        shopBindEntity.setShopId(shopEntity.getId());
        shopBindEntity.setMerchantType(MerchantTypeEnum.PARENT);
        shopBindRepository.save(shopBindEntity);

        // 初始化店铺菜单信息
        InitShopMenuDTO initShopMenuDTO = new InitShopMenuDTO();
        initShopMenuDTO.setShopId(shopEntity.getId());
        initShopMenuDTO.setUserId(userId);
        userClient.initShopMenu(initShopMenuDTO);

        return Result.ok();
    }

    /**
     * 查询用户店铺列表
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    public Result userShopList(Integer pageNum, Integer pageSize) {
        Long merchantId = ShopRequestContextHolder.getMerchantId();
        IPage<ShopBindEntity> shopEntityIPage = shopBindRepository.selectShopListByMerchantId(pageNum, pageSize, merchantId);
        PageVO<UserShopPageDTO> shopPageVO = new PageVO<>();
        List<UserShopPageDTO> userShopPageDTOList = new ArrayList<>();
        for (ShopBindEntity shopBindEntity : shopEntityIPage.getRecords()) {
            ShopEntity shopEntity = shopRepository.getById(shopBindEntity.getShopId());
            Assert.notNull(shopBindEntity, "店铺不存在");

            // 查询店铺审核信息
            ShopIdentificationEntity shopIdentificationEntity = shopIdentificationRepository.getByShopId(shopBindEntity.getShopId());
            Assert.notNull(shopIdentificationEntity, "店铺审核信息不存在！");

            UserShopPageDTO userShopPageDTO = new UserShopPageDTO();
            userShopPageDTO.setShopId(shopEntity.getId());
            userShopPageDTO.setShopLogo(shopEntity.getShopLogo());
            userShopPageDTO.setShopName(shopEntity.getUniqueShopName());
            userShopPageDTO.setVerifyStatus(shopIdentificationEntity.getVerifyStatus().getCode());
            userShopPageDTO.setShopExplain(shopEntity.getShopExplain());
            userShopPageDTOList.add(userShopPageDTO);
        }
        shopPageVO.assemblePage(shopEntityIPage);
        shopPageVO.setRecords(userShopPageDTOList);
        return Result.ok().putData(shopPageVO);
    }

    /**
     * 查询店铺绑定商户
     *
     * @param shopId
     * @return
     */
    public Result listMerchantByShopId(Long shopId) {
        List<ShopBindEntity> shopBindEntityList = shopBindRepository.listByShopId(shopId);
        List<Long> merchantIds = new ArrayList<>();
        for (ShopBindEntity shopBindEntity : shopBindEntityList) {
            merchantIds.add(shopBindEntity.getMerchantId());
        }

        return Result.ok().putData(merchantIds);
    }

    /**
     * 店铺绑定商户
     *
     * @param shopId
     * @param merchantIds
     * @return
     */
    public Result bindMerchants(Long shopId, List<Long> merchantIds) {
        List<ShopBindEntity> shopBindEntityList = shopBindRepository.listByShopIdAndMerchantIds(shopId, merchantIds);
        for (Long merchantId : merchantIds) {
            boolean matched = shopBindEntityList.stream().anyMatch(e -> e.getMerchantId().equals(merchantId));
            if (matched) {
                ShopBindEntity shopBindEntity = shopBindEntityList
                        .stream()
                        .filter(e -> e.getMerchantId().equals(merchantId))
                        .findFirst()
                        .get();
                if (ShopBindStatusEnum.OFF == shopBindEntity.getShopBindStatus()) {
                    shopBindEntity.setShopBindStatus(ShopBindStatusEnum.ON);
                    shopBindEntityList.add(shopBindEntity);
                }
            } else {
                ShopBindEntity shopBindEntity = new ShopBindEntity();
                shopBindEntity.setShopId(shopId);
                shopBindEntity.setMerchantType(MerchantTypeEnum.SUB);
                shopBindEntity.setShopBindStatus(ShopBindStatusEnum.ON);
                shopBindEntity.setMerchantId(merchantId);
                shopBindEntityList.add(shopBindEntity);
            }
        }

        shopBindRepository.saveOrUpdateBatch(shopBindEntityList);
        return Result.ok();
    }
}
